package com.css.bjdt_core.reportClone.service;

import java.io.File;
import java.io.FileInputStream;
import java.sql.Date;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.css.bjdt_core.cell.entity.Cell;
import com.css.bjdt_core.explain.entity.RptCellExplain;
import com.css.bjdt_core.explain.entity.RptTemplateExplain;
import com.css.bjdt_core.report.entity.RptAreaCategoryR;
import com.css.bjdt_core.report.entity.RptAreaTemporary;
import com.css.bjdt_core.report.entity.RptTemplate;
import com.css.bjdt_core.report.entity.RptTemplateCalc;
import com.css.bjdt_core.report.entity.RptTemplateCloneInfo;
import com.css.bjdt_core.report.entity.RptTemplateCondition;
import com.css.bjdt_core.report.entity.RptTemplateValidation;
import com.css.bjdt_core.report.service.ReportTemplateManageService;
import com.css.bjdt_core.reportPrepare.entity.ViewRptGroupTemplate;
import com.css.bjdt_core.util.CommonUtil;
import com.css.bjdt_core.validation.service.ReportValidationFormulaOnloadService;

@Service
public class ReportCloneService {

	@Autowired
	private Dao dao;

	private Map<String, String> rptExplainIdMap = new HashMap<String, String>();

	@Autowired
	private ReportTemplateManageService reportTemplateManageService;

	@Autowired
	private ReportValidationFormulaOnloadService reportValidationFormulaOnloadService;

	/**
	 * 克隆单张报表的基本信息
	 * @param templateOldId  历史报表的ID
	 * @param templateNewId  历史报表的ID
	 * @param groupId  新套表的ID，也就是克隆到哪个套表下面的套表ID
	 * @return 返回新报表的报表ID
	 */
	public void reportInfoClone(String templateOldId, String templateNewId, String groupId) {
		RptTemplate rptTemplate = dao.fetch(RptTemplate.class, templateOldId);
		rptTemplate.setTemplateId(templateNewId);
		rptTemplate.setGroupId(groupId);
		Date date = new Date(new java.util.Date().getTime());
		rptTemplate.setCreateDate(date);
		dao.insert(rptTemplate);
	}

	/**
	 * 克隆单张报表的模板
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @param annualNewId  新年度的ID
	 * @param annualOldId  老年度的ID
	 * @return
	 */
	public void reportTemplateClone(String templateNewId, String templateOldId, String annualNewId,
			String annualOldId) {
		String url = CommonUtil.readProperties();
		String fileOldName = templateOldId + ".cll";
		String fileNewName = templateNewId + ".cll";
		File cellOldFile = new File(url + "/" + annualOldId + "/", fileOldName);
		File cellNewFile = new File(url + "/" + annualNewId + "/", fileNewName);
		if (cellOldFile.exists()) {
			try {
				FileInputStream in = new FileInputStream(cellOldFile);
				FileUtils.copyInputStreamToFile(in, cellNewFile);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 克隆单张报表的所有单元格属性
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @return
	 */
	public void reportCellClone(String templateNewId, String templateOldId) {
		List<Cell> cellList = dao.query(Cell.class, Cnd.where("TEMPLATE_ID", "=", templateOldId));
		List<Cell> cellListNew = new ArrayList<Cell>();
		for (Cell cell : cellList) {
			String newId = CommonUtil.getUUID();
			cell.setCellId(newId);
			cell.setTemplateId(templateNewId);
			cellListNew.add(cell);
		}
		dao.insert(cellListNew);
	}

	/**
	 * 克隆单张报表的数据区域
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @return
	 */
	public Map<String, String> reportTemporaryClone(String templateNewId, String templateOldId) {
		List<RptAreaTemporary> rptAreaTemporaryList = dao.query(RptAreaTemporary.class,
				Cnd.where("TEMPLATEID", "=", templateOldId));
		//存一张报表的区域ID新老的对应关系
		Map<String, String> temporaryIdMap = new HashMap<String, String>();
		for (RptAreaTemporary rptAreaTemporary : rptAreaTemporaryList) {
			RptAreaCategoryR rptAreaCategoryR = dao.fetch(RptAreaCategoryR.class,
					Cnd.where("AREA_ID", "=", rptAreaTemporary.getId()));
			//克隆报表区域
			String rptAreaTemporaryNewId = CommonUtil.getUUID();
			temporaryIdMap.put(rptAreaTemporary.getId(), rptAreaTemporaryNewId);
			rptAreaTemporary.setTemplateId(templateNewId);
			rptAreaTemporary.setId(rptAreaTemporaryNewId);
			//克隆报表区域和统计信息集的关系
			String rptAreaCategoryRNewId = CommonUtil.getUUID();
			rptAreaCategoryR.setId(rptAreaCategoryRNewId);
			rptAreaCategoryR.setAreaId(rptAreaTemporaryNewId);
			dao.insert(rptAreaTemporary);
			dao.insert(rptAreaCategoryR);
		}
		return temporaryIdMap;
	}

	/**
	 * 克隆单张报表的计算公式
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @return
	 */
	public void reportCalcClone(String templateNewId, String templateOldId, Map<String, String> temporaryIdMap) {
		List<RptTemplateCalc> rptTemplateCalcList = dao.query(RptTemplateCalc.class,
				Cnd.where("TEMPLATE_ID", "=", templateOldId));
		List<RptTemplateCalc> rptTemplateCalcListNew = new ArrayList<RptTemplateCalc>();
		for (RptTemplateCalc rptTemplateCalc : rptTemplateCalcList) {
			String newId = CommonUtil.getUUID();
			rptTemplateCalc.setCalcId(newId);
			rptTemplateCalc.setTemplateId(templateNewId);
			String areaTemporaryOldId = rptTemplateCalc.getAreaTemporaryId();
			if (!("").equals(areaTemporaryOldId) || null != areaTemporaryOldId) {
				rptTemplateCalc.setAreaTemporaryId(temporaryIdMap.get(areaTemporaryOldId));
			}
			rptTemplateCalcListNew.add(rptTemplateCalc);
		}
		dao.insert(rptTemplateCalcListNew);
	}

	/**
	 * 克隆单张报表的所有条件
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @return
	 */
	public void reportConditionsClone(String templateNewId, String templateOldId, Map<String, String> temporaryIdMap) {
		List<RptTemplateCondition> rptTemplateConditionList = dao.query(RptTemplateCondition.class,
				Cnd.where("TEMPLATE_ID", "=", templateOldId));
		List<RptTemplateCondition> rptTemplateConditionNewList = new ArrayList<RptTemplateCondition>();
		for (RptTemplateCondition rptTemplateCondition : rptTemplateConditionList) {
			String newId = CommonUtil.getUUID();
			rptTemplateCondition.setConditionId(newId);
			rptTemplateCondition.setTemplateId(templateNewId);
			String areaTemporaryOldId = rptTemplateCondition.getAreaTemporaryId();
			if (!("").equals(areaTemporaryOldId) || null != areaTemporaryOldId) {
				rptTemplateCondition.setAreaTemporaryId(temporaryIdMap.get(areaTemporaryOldId));
			}
			rptTemplateConditionNewList.add(rptTemplateCondition);
		}
		dao.insert(rptTemplateConditionNewList);
	}

	/**
	 * 克隆单张报表的所有校核公式
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @return
	 */
	public void reportValidationClone(String templateNewId, String templateOldId) {
		List<RptTemplateValidation> rptTemplateValidationList = dao.query(RptTemplateValidation.class,
				Cnd.where("TEMPLATE_ID", "=", templateOldId));
		List<RptTemplateValidation> rptTemplateValidationNewList = new ArrayList<RptTemplateValidation>();
		for (RptTemplateValidation rptTemplateValidation : rptTemplateValidationList) {
			String newId = CommonUtil.getUUID();
			rptTemplateValidation.setTemplateId(templateNewId);
			rptTemplateValidation.setValidationId(newId);
			rptTemplateValidationNewList.add(rptTemplateValidation);
		}
		dao.insert(rptTemplateValidationNewList);
	}

	/**
	 * 克隆单张报表的所有报表说明
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @param annualNewId  新年度的年度ID
	 * @return 注意返回的新报表和老报表的MAP(一定注意)
	 */
	public Map<String, String> reportExplainInfoClone(String templateNewId, String templateOldId, String annualNewId) {
		List<RptTemplateExplain> rptTemplateExplainList = dao.query(RptTemplateExplain.class,
				Cnd.where("TEMPLATE_ID", "=", templateOldId));
		List<RptTemplateExplain> rptTemplateExplainNewList = new ArrayList<RptTemplateExplain>();
		List<String> explainOldIds = new ArrayList<String>();
		Map<String, String> explainNewIdsMap = new HashMap<String, String>();
		for (RptTemplateExplain rptTemplateExplain : rptTemplateExplainList) {
			String newId = CommonUtil.getUUID();
			explainNewIdsMap.put(rptTemplateExplain.getId(), newId);
			rptTemplateExplain.setId(newId);
			rptTemplateExplain.setTemplateId(templateNewId);
			rptTemplateExplain.setAnnualId(annualNewId);
			rptTemplateExplainNewList.add(rptTemplateExplain);
			explainOldIds.add(rptTemplateExplain.getId());
		}
		dao.insert(rptTemplateExplainNewList);
		return explainNewIdsMap;
	}

	/**
	 * 克隆单张报表的所有报表说明的单元格属性
	 * @param templateNewId  新报表的ID
	 * @param templateOldId  老报表的ID
	 * @param annualNewId  新年度的年度ID
	 * @return
	 */
	public void reportExplainCellClone(String templateNewId, String templateOldId) {
		List<RptTemplateExplain> rptTemplateExplainList = dao.query(RptTemplateExplain.class,
				Cnd.where("TEMPLATE_ID", "=", templateOldId));
		List<RptCellExplain> rptCellExplainNewList = new ArrayList<RptCellExplain>();
		for (RptTemplateExplain rptTemplateExplain : rptTemplateExplainList) {
			List<RptCellExplain> rptCellExplainList = dao.query(RptCellExplain.class,
					Cnd.where("EXPLAIN_ID", "=", rptTemplateExplain.getId()));
			for (RptCellExplain rptCellExplain : rptCellExplainList) {
				String newId = CommonUtil.getUUID();
				rptCellExplain.setCellExplainId(newId);
				rptCellExplain.setExplainId(rptExplainIdMap.get(rptCellExplain.getExplainId()));
				rptCellExplainNewList.add(rptCellExplain);
			}
		}
		dao.insert(rptCellExplainNewList);
	}

	public void reportExplainTemplateClone(Map<String, String> explainNewIdsMap, String annualNewId,
			String annualOldId) {
		Iterator iterator = explainNewIdsMap.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry entity = (Map.Entry) iterator.next();
			String url = CommonUtil.readProperties();
			String fileOldName = entity.getKey() + ".cll";
			String fileNewName = entity.getValue() + ".cll";
			File cellOldFile = new File(url + "/" + annualOldId + "/explain" + "/", fileOldName);
			File cellNewFile = new File(url + "/" + annualNewId + "/explain" + "/", fileNewName);
			if (cellOldFile.exists()) {
				try {
					FileInputStream in = new FileInputStream(cellOldFile);
					FileUtils.copyInputStreamToFile(in, cellNewFile);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public boolean saveTemplateCloneInfo(String templateOldId, String templateNewId, String annualNewId,
			String annualOldId) {
		RptTemplateCloneInfo rptTemplateCloneInfo = dao.fetch(RptTemplateCloneInfo.class,
				Cnd.where("TEMPLATE_OLD_ID", "=", templateOldId).and("ANNUAL_NEW_ID", "=", annualNewId)
						.and("ANNUAL_OLD_ID", "=", annualOldId));
		if (null == rptTemplateCloneInfo) {
			rptTemplateCloneInfo = new RptTemplateCloneInfo();
			rptTemplateCloneInfo.setAnnualNewId(annualNewId);
			rptTemplateCloneInfo.setAnnualOldId(annualOldId);
			rptTemplateCloneInfo.setTemplateNewId(templateNewId);
			rptTemplateCloneInfo.setTemplateOldId(templateOldId);
			dao.insert(rptTemplateCloneInfo);
			return true;
		} else {
			return false;
		}
	}

	@Transactional
	public String reportAllInfoClone(String templateOldId, String groupId, String annualNewId, String annualOldId) {
		try {
			String templateNewId = CommonUtil.getUUID();
			//将旧的报表ID和新的报表ID对应信息存入表里
			boolean isHaveClone = saveTemplateCloneInfo(templateOldId, templateNewId, annualNewId, annualOldId);
			if (isHaveClone) {
				//报表基本信息克隆
				reportInfoClone(templateOldId, templateNewId, groupId);
				//报表模板克隆
				reportTemplateClone(templateNewId, templateOldId, annualNewId, annualOldId);
				//报表单元格克隆
				reportCellClone(templateNewId, templateOldId);
				//数据区域的克隆
				Map<String, String> temporaryIdMap = reportTemporaryClone(templateNewId, templateOldId);
				//报表公式的克隆
				reportCalcClone(templateNewId, templateOldId, temporaryIdMap);
				//报表的行列条件克隆
				reportConditionsClone(templateNewId, templateOldId, temporaryIdMap);
				//报表的校核公式克隆
				reportValidationClone(templateNewId, templateOldId);
				//报表说明的基本信息克隆
				Map<String, String> explainNewIdsMap = reportExplainInfoClone(templateNewId, templateOldId,
						annualNewId);
				//报表说明的单元格信息克隆
				reportExplainCellClone(templateNewId, templateOldId);
				//报表说明模板的克隆
				reportExplainTemplateClone(explainNewIdsMap, annualNewId, annualOldId);
			}
			return "";
		} catch (Exception e) {
			System.out.println(e);
			e.printStackTrace();
			RptTemplate rptTemplate = dao.fetch(RptTemplate.class, Cnd.where("TEMPLATEID", "=", templateOldId));
			return rptTemplate.getName();
		}
	}

	public void reloadValidationFormual(String annualNewId) {
		List<RptTemplateCloneInfo> rptTemplateCloneInfoList = dao.query(RptTemplateCloneInfo.class,
				Cnd.where("ANNUAL_NEW_ID", "=", annualNewId));
		for (RptTemplateCloneInfo rptTemplateCloneInfo : rptTemplateCloneInfoList) {
			//重新生成新的标间关系公式
			onloadReportBetweenValidationFormual(rptTemplateCloneInfo.getTemplateNewId(), annualNewId);
			//重新生成新的表内校核
			reportValidationFormulaOnloadService.onloadValidationCellFormula(rptTemplateCloneInfo.getTemplateNewId());
		}

	}

	//重新加载表间校核公式
	public void onloadReportBetweenValidationFormual(String templateNewId, String annualNewId) {
		List<RptTemplateValidation> validationInfoList = dao.query(RptTemplateValidation.class,
				Cnd.where("TEMPLATE_ID", "=", templateNewId).and("VALIDATION_TYPE", "=", "4"));
		String strSql = "update RPT_TEMPLATE_VALIDATION set VALIDATION_FORMULA = @validationFormula "
				+ ", VALIDATION_FORMULA_SHOW=@validationFormulaShow, VALIDATION_FORMULA_REL=@validationFormulaRel where VALIDATION_ID = @validationId";
		Sql sql = Sqls.create(strSql);
		for (RptTemplateValidation rptTemplateValidation : validationInfoList) {
			String validationFormulaRel = rptTemplateValidation.getValidationFormulaRel();
			String validationFormulaShowTemplateId = rptTemplateValidation.getValidationFormulaRel();
			//第一步先将公式拆成左右两个部分
			String validationFormula = rptTemplateValidation.getValidationFormulaRel();
			String[] validationNum = validationFormula.split("[\\=\\>\\<\\=>\\=</]");
			//第一步先将公式拆成左右两个部分
			String leftValidationFormula = validationNum[0];
			String rightValidationFormula = validationNum[1];
			try {
				if (rightValidationFormula.length() == 0 || rightValidationFormula.length() == 1) {
					rightValidationFormula = validationNum[2];
				} else {
					rightValidationFormula = validationNum[1];
				}
			} catch (Exception e) {
				System.out.println("------------------>" + validationFormula);
			}

			//先拆左边
			String[] leftValidationFormulaArray = leftValidationFormula.split("[\\+\\-\\*\\=\\>\\</]");
			for (String cellCoordinate : leftValidationFormulaArray) {
				String numStr = cellCoordinate.replaceAll("[a-zA-Z]", "");
				String letterStr = cellCoordinate.replaceAll("[0-9]", "");
				String letterNumStr = CommonUtil.letterToNum(letterStr);
				Cell cell = null;
				cell = dao.fetch(Cell.class, Cnd.where("TEMPLATE_ID", "=", templateNewId)
						.and("REL_ROW_NUM", "=", numStr).and("REL_COL_NUM", "=", letterNumStr));
				if (cell == null) {
					cell = dao.fetch(Cell.class, Cnd.where("TEMPLATE_ID", "=", templateNewId)
							.and("ABS_ROW_NUM", "=", numStr).and("ABS_COL_NUM", "=", letterNumStr));
				}
				if (cell == null) {
					continue;
				} else {
					validationFormula = validationFormula.replaceFirst(cellCoordinate, cell.getCellId());
				}
			}
			//再拆右边
			String[] rightValidationFormulaArray = rightValidationFormula.split("[\\+\\-\\*\\=\\>\\</]");
			for (String cellString : rightValidationFormulaArray) {
				String[] cellStringArray = cellString.split("[\\./]");
				String templateIdValidation = cellStringArray[0];
				String templateIdValidationNew = "";
				RptTemplateCloneInfo rptTemplateCloneInfo = dao.fetch(RptTemplateCloneInfo.class,
						Cnd.where("TEMPLATE_OLD_ID", "=", templateIdValidation).and("ANNUAL_NEW_ID", "=", annualNewId));
				if (null != rptTemplateCloneInfo) {
					templateIdValidationNew = rptTemplateCloneInfo.getTemplateNewId();
					//替换validationFormulaRel
					validationFormulaRel = validationFormulaRel.replaceAll(templateIdValidation,
							templateIdValidationNew);
					templateIdValidation = rptTemplateCloneInfo.getTemplateNewId();
				}

				ViewRptGroupTemplate viewRptGroupTemplate = null;
				Cell cell = null;
				try {
					viewRptGroupTemplate = reportTemplateManageService.getAViewRptGroupTemplate(templateIdValidation);
					String cellCoordinate = cellStringArray[1];
					String numStr = cellCoordinate.replaceAll("[a-zA-Z]", "");
					String letterStr = cellCoordinate.replaceAll("[0-9]", "");
					String letterNumStr = CommonUtil.letterToNum(letterStr);

					cell = dao.fetch(Cell.class, Cnd.where("TEMPLATE_ID", "=", templateIdValidation)
							.and("REL_ROW_NUM", "=", numStr).and("REL_COL_NUM", "=", letterNumStr));
					if (cell == null) {
						cell = dao.fetch(Cell.class, Cnd.where("TEMPLATE_ID", "=", templateIdValidation)
								.and("ABS_ROW_NUM", "=", numStr).and("ABS_COL_NUM", "=", letterNumStr));
					}
					if (cell == null) {
						System.out.println("--------------" + cellString + "------------------");
					}
				} catch (Exception e) {
					System.out.println(viewRptGroupTemplate.getTemplateId());
					e.printStackTrace();
				}

				if (null != cell) {
					validationFormula = validationFormula.replaceFirst(cellString, cell.getCellId());
				}

				/*这里是这样的，假如表间校核公式是A1>第二表.A1  数据库里面存的有A1>第二表ID.A1 那么通过ID来查到第二表的名字，然后用替换表ID的这个
				  	公式，形成新的展现公式，再存到校核表的展示公式字段下面
				*/
				validationFormulaShowTemplateId = validationFormulaShowTemplateId.replaceFirst(cellStringArray[0],
						viewRptGroupTemplate.getTemplateName());
				//validationFormulaShow = validationFormulaShow.replaceFirst(cellStringArray[0], newTemplateName);
			}

			//判断当前公式是否有=号
			if (!(validationFormula.contains(">") || validationFormula.contains("<"))) {
				validationFormula = validationFormula.replaceFirst("=", "==");
			}
			sql.params().set("validationFormula", validationFormula)
					.set("validationId", rptTemplateValidation.getValidationId())
					.set("validationFormulaShow", validationFormulaShowTemplateId)
					.set("validationFormulaRel", validationFormulaRel);
			dao.execute(sql);
		}
	}

	public void abc() {

	}
}
